package com.example.intermingle.service;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.intermingle.Constants;
import com.example.intermingle.dto.JqGridPageDto;
import com.example.intermingle.dto.RoleEditAndDelDto;
import com.example.intermingle.mapper.RoleMapper;
import com.example.intermingle.mapper.UserRoleMapper;
import com.example.intermingle.util.CommonUtils;
import com.example.intermingle.vo.Role;
import com.example.intermingle.vo.User;
import com.example.intermingle.vo.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 绿松石
 * @version V1.0
 * @Title RoleService
 * @Description   角色处理类
 * @date 2021年09月10日 10:32
 * @since V1.0
 */
@Service
public class RoleService {

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    /**
     *查找所有的权限
     * @return
     */
    public JqGridPageDto<RoleEditAndDelDto> selectUserRole(Integer userId) {
        //定义对象
        JqGridPageDto<RoleEditAndDelDto> roleJqGridPageDto=new JqGridPageDto<>();
        //查询角色信息
        List<Role> roles=roleMapper.selectUserRole(null,null);
        //定义一个对象
        List<RoleEditAndDelDto> roleEditAndDelDtos=new ArrayList<>();
        //由于修改和删除没办法传递用户id，更改查询方法
        for(int i=0;i<roles.size();i++){
            //定义一个对象
            RoleEditAndDelDto roleEditAndDelDto=new RoleEditAndDelDto();
            //进行赋值
            roleEditAndDelDto.setUserId(userId);
            roleEditAndDelDto.setRoleName(roles.get(i).getRoleName());
            roleEditAndDelDto.setRoleId(roles.get(i).getRoleId());
            roleEditAndDelDto.setRoleAuthority(roles.get(i).getRoleAuthority());
            roleEditAndDelDto.setCreatedBy(roles.get(i).getCreatedBy());
            roleEditAndDelDto.setCreatedDate(roles.get(i).getCreatedDate());
            roleEditAndDelDto.setUpdateBy(roles.get(i).getUpdateBy());
            roleEditAndDelDto.setUpdateDate(roles.get(i).getUpdateDate());
            //添加到list集合
            roleEditAndDelDtos.add(roleEditAndDelDto);
        }
        //赋值
        roleJqGridPageDto.setRows(roleEditAndDelDtos);
        //返回数据
        return roleJqGridPageDto;
    }

    /**
     *
     * 根据用户id来查询数据
     * @param userId
     * @return
     */

    public JqGridPageDto<Role> selectSingleUserRole(Integer userId) {
        //定义对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //查询的权限信息
        List<Role> roles=roleMapper.selectSingleUserRole(  userId);

        //赋值
        roleJqGridPageDto.setRows(roles);
        return  roleJqGridPageDto;
    }


    /**
     *  进行新增用户权限（该方法的逻辑是传过来的数据跟查数据库的数据来对比，放到roleList,在定义一个用户角色
     *  关联表进行依次添加）
     * @param roleEditAndDelDtos 传过来的用户权限
     * @return
     */
    public JqGridPageDto<Role> addUserRole(List<RoleEditAndDelDto> roleEditAndDelDtos) {
        //定义对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //查询的权限信息
        List<Role> roles=roleMapper.selectSingleUserRole( roleEditAndDelDtos.get(0).getUserId());
        List<Role> rolsList=new ArrayList<>();
        //传过来的list长度
        int roleEdiSize=roleEditAndDelDtos.size();
        //查询出来的list长度
        int roleSize=roles.size();
        //页面传过来的权限信息
        for(int i=0;i<roleEdiSize;i++){
            //判断查到的对象是否为空，为空就直接添加，不对比
            if(roleSize==0){
                //定义一个role对象
                Role role=new Role();
                //赋值
                role.setRoleId(roleEditAndDelDtos.get(i).getRoleId());
                role.setRoleName(roleEditAndDelDtos.get(i).getRoleName());
                role.setRoleAuthority(roleEditAndDelDtos.get(i).getRoleAuthority());
                role.setCreatedBy(CommonUtils.getName());
                role.setCreatedDate(new Date());
                role.setUpdateBy(CommonUtils.getName());
                role.setUpdateDate(new Date());

                //跟删除是相反的
                //不一致的权限添加到rolsList，切记，该list存放的跟数据库查询不一样的页面角色信息
                rolsList.add(role);
            }else{
                int frequency=1;
                //根据用户id查询出来的用户信息
                for(int j=0;j<roleSize;j++){
                    //判断取到的权限不一致
                    if(roleEditAndDelDtos.get(i).getRoleId().equals(roles.get(j).getRoleId())){
                        frequency=0;
                    }
                }
                if(frequency==1){
                    //定义一个role对象
                    Role role=new Role();
                    //赋值
                    role.setRoleId(roleEditAndDelDtos.get(i).getRoleId());
                    role.setRoleName(roleEditAndDelDtos.get(i).getRoleName());
                    role.setRoleAuthority(roleEditAndDelDtos.get(i).getRoleAuthority());
                    role.setCreatedBy(CommonUtils.getName());
                    role.setCreatedDate(new Date());
                    role.setUpdateBy(CommonUtils.getName());
                    role.setUpdateDate(new Date());

                    //跟删除是相反的
                    //不一致的权限添加到rolsList，切记，该list存放的跟数据库查询不一样的页面角色信息
                    rolsList.add(role);
                }
            }
        }
        //for循环添加权限
        for(int i=0;i<rolsList.size();i++){
            //定义用户权限对象
            UserRole userRole=new UserRole();
            //进行赋值
            userRole.setRoleId(rolsList.get(i).getRoleId());
            userRole.setUserId(roleEditAndDelDtos.get(0).getUserId());
            userRole.setCreatedBy(CommonUtils.getName());
            userRole.setUpdateBy(CommonUtils.getName());
            userRole.setCreatedDate(new Date());
            userRole.setUpdateDate(new Date());
            //添加用户权限
            int count=userRoleMapper.insertAll(userRole);
        }

        //赋值
        roleJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.ADD_SUCCESS);
        return  roleJqGridPageDto;
    }

    /**
     * 删除用户权限（该方法的逻辑是传过来的数据跟查数据库的数据来对比，放到roleList,通过用户id和角色id
     * 进行依次删除）
     * @param roleEditAndDelDtosd 传过来的权限信息
     * @return
     */
    public JqGridPageDto<Role> delUserRole(List<RoleEditAndDelDto> roleEditAndDelDtosd) {

        //定义对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();

        List<Role> rolsList=new ArrayList<>();
        if(!roleEditAndDelDtosd.isEmpty()){
            //查询用户的权限信息
            List<Role> roles=roleMapper.selectSingleUserRole( roleEditAndDelDtosd.get(0).getUserId());
            //页面传过来的权限信息
            for(int i=0;i<roles.size();i++){
                //查出来的角色为空，直接返回异常
                if(roles.isEmpty()){
                    roleJqGridPageDto.setErrorMsg(Constants.FAILCode.DELECT_FAIL);
                    return  roleJqGridPageDto;
                }else{
                    int frequency=1;
                    //根据用户id查询出来的用户信息
                    for(int j=0;j<roleEditAndDelDtosd.size();j++){
                        //判断取到的权限不一致
                        if(roleEditAndDelDtosd.get(j).getRoleId().equals(roles.get(i).getRoleId())){
                            frequency=0;
                        }
                        if(frequency==1){
                            rolsList.add(roles.get(i));
                        }

                    }
                }
            }
        }

        String text=null;
        //for循环删除权限
        for(int i=0;i<rolsList.size();i++){
            //根据用户id和角色id来查询用户角色权限
           UserRole userRole=userRoleMapper.selectOneByUserIdAndRoleId(roleEditAndDelDtosd.get(0).getUserId(),rolsList.get(i).getRoleId());
           //判断对象userRole不为空
           if(userRole!=null){
               //不为空进行删除角色权限信息
               int count =userRoleMapper.delByUserRoleId(userRole.getUserRoleId());
               if(count==1){
                   text=text+","+"用户id："+rolsList.get(i).getRoleId()+Constants.SUCCESSCode.DELECT_SUCCESS;
               }else{
                   text=text+","+"用户id："+rolsList.get(i).getRoleId()+Constants.FAILCode.DELECT_FAIL;
               }
           }
        }

        roleJqGridPageDto.setErrorMsg(text);
        return  roleJqGridPageDto;
    }

    /**
     * 根据条件查询角色信息
     * @param page  当前页数
     * @param size 条数
     * @param roleId  角色id
     * @param roleName   角色名称
     * @param roleAuthority   角色权限
     * @return
     */
    public JqGridPageDto<Role> selectAllRole(Integer page, Integer size, Integer roleId, String roleName, String roleAuthority) {
        if (page != null && size != null) {
            page = (page - 1) * size;
        }
        //根据条件查询角色信息
        List<Role> roles=roleMapper.selectAllRole(page,size,roleId,roleName,roleAuthority);
        //查询总页数
        Long records=roleMapper.getTotal(roleId,roleName,roleAuthority);
        //定义一个对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //赋值
        roleJqGridPageDto.setRows(roles);
        roleJqGridPageDto.setRecords(records);
        return roleJqGridPageDto;
    }

    /**
     * 添加角色
     * @param roleName  角色名称
     * @param roleAuthority  角色权限
     * @return
     */
    public JqGridPageDto<Role> addRole(String roleName, String roleAuthority) {
        //定义一个对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //定义一个角色对象
        Role role=new Role();
        //赋值
        role.setRoleName(roleName);
        role.setRoleAuthority(roleAuthority);
        role.setCreatedBy(CommonUtils.getName());
        role.setUpdateBy(CommonUtils.getName());;
        role.setCreatedDate(new Date());
        role.setUpdateDate(new Date());
        int count =roleMapper.addAll(role);
        if(count==1){
            roleJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.ADD_SUCCESS);
        }else {
            roleJqGridPageDto.setErrorMsg(Constants.FAILCode.ADD_FAIL);
        }
        return roleJqGridPageDto;
    }

    /**
     * 编辑角色
     * @param role
     * @return
     */
    public JqGridPageDto<Role> editRole(Role role) {
        //定义一个对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //定义一个角色对象
        //Role roles=new Role();
        role.setRoleName(role.getRoleName());
        role.setRoleAuthority(role.getRoleAuthority());
        role.setUpdateDate(new Date());
        role.setUpdateBy(CommonUtils.getName());
        //根据对象来修改角色信息
        int count =roleMapper.updateRole(role);
        if(count==1){
            roleJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.UPDATE_SUCCESS);
        }else {
            roleJqGridPageDto.setErrorMsg(Constants.FAILCode.UPDATE_FAIL);
        }
        return roleJqGridPageDto;
    }

    /**
     * 根据角色id来删除角色
     * @param roleId 角色id
     * @return
     */
    public JqGridPageDto<Role> delRole(Integer roleId) {
        //定义一个对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //根据id来删除角色
        int count =roleMapper.delByRoleId(roleId);
        if(count==1){
            roleJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.DELECT_SUCCESS);
        }else {
            roleJqGridPageDto.setErrorMsg(Constants.FAILCode.DELECT_FAIL);
        }
        return roleJqGridPageDto;
    }

    /**
     * 导入角色
     * @param request
     * @return
     */
    public JqGridPageDto<Role> imporRole(HttpServletRequest request) {
        //定义一个对象
        JqGridPageDto<Role> roleJqGridPageDto=new JqGridPageDto<>();
        //定义一个MultipartHttpServletRequest对象
        MultipartHttpServletRequest multipartRequest =null;
        //判断里面有没有文件
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest)(request);
        }
        //统计导入成功数
        int successCount=0;
        //统计导入失败数
        int failCount=0;
        //获取文件流，写入list集合
        List<MultipartFile> files = multipartRequest.getFiles("file");
        //存在多个文件，用for循环
        for(int i=0;i<files.size();i++){
            try {
                //写入字节输入流
                InputStream inputStream=files.get(i).getInputStream();
                ExcelReader excelReader= ExcelUtil.getReader(inputStream,"sheet1");
                //加入表头名称和封装对象的名称
                excelReader.addHeaderAlias("角色名称","roleName");
                excelReader.addHeaderAlias("角色权限","roleAuthority");

                //获取文档的内容
                List<Role> roles=excelReader.readAll(Role.class);
                String error=checkRoleImport(roles);
                if(!error.equals(null)){
                    roleJqGridPageDto.setErrorMsg(error);
                }
                for(int j=0;j<roles.size();j++){
                    //定义一个角色对象
                    Role role=new Role();
                    //赋值
                    role.setRoleName(roles.get(i).getRoleName());
                    role.setRoleAuthority(roles.get(i).getRoleAuthority());
                    role.setCreatedBy(CommonUtils.getName());
                    role.setUpdateBy(CommonUtils.getName());;
                    role.setCreatedDate(new Date());
                    role.setUpdateDate(new Date());
                    int count=roleMapper.addAll(role);
                    //插入成功
                    if(count==1){
                        //成功次数加1
                        successCount=successCount+1;
                    }else{
                        //失败次数加1
                        failCount=failCount+1;
                    }
                }
                roleJqGridPageDto.setErrorMsg("导入数"+(successCount+failCount)+"成功条数"+successCount+"失败条数"+failCount);
            }catch (Exception e){
                roleJqGridPageDto.setErrorMsg("导入失败");
            }
        }
        return roleJqGridPageDto;
    }

    /**
     * 角色导出
     * @param page
     * @param size
     * @param response
     */
    public void exportRole(Integer page, Integer size, HttpServletResponse response) {
        if (page != null && size != null) {
            page = (page - 1) * size;
        }
        //根据条件查询角色信息
        List<Role> roles=roleMapper.selectAllRole(page,size,null,null,null);

        //模板名称
        String fileName=Constants.TEMPLATE_EXPORT_ROLE;
        //创建一个ExcelWriter
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //给字段标值
        writer.addHeaderAlias("roleId","角色id");
        writer.addHeaderAlias("roleName","角色名称");
        writer.addHeaderAlias("roleAuthority","角色权限");
        writer.addHeaderAlias("createdBy","创建人员");
        writer.addHeaderAlias("updateBy","更新人员");
        writer.addHeaderAlias("createdDate","创建时间");
        writer.addHeaderAlias("updateDate","修改时间");
        writer.addHeaderAlias("validFlag","");
        writer.write(roles, true);
        try {
            // 获取我们的输出流
            final OutputStream output = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=utf-8''"
                    + URLEncoder.encode(fileName, Constants.CODING_UTF8));
            writer.flush(output, true);
            writer.close();
            output.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 校验角色导入数据
     * @param roles
     * @return
     */
    private String checkRoleImport(List<Role> roles){
        //角色名称错误信息
        String roleNameError="";
        //角色权限错误信息
        String roleAuthorityError="";
        for(int i=0;i<roles.size();i++){
            if (!CommonUtils.isNotNull(roles.get(i).getRoleName())){
                roleNameError=Constants.importCheck.ROLEIMPORT_ROLE_ROLENAME;
            }
            if (!CommonUtils.isNotNull(roles.get(i).getRoleAuthority())){
                roleAuthorityError=Constants.importCheck.ROLEIMPORT_ROLE_ROLEAUTHORITY;
            }

        }
        //两个错误信息都没有。直接返回null
        if(!roleNameError.isEmpty()&&!roleAuthorityError.isEmpty()){
            return  roleNameError+roleNameError;
        }
        return   null;

    }
}
